/*
 * @lc app=leetcode.cn id=36 lang=typescript
 *
 * [36] 有效的数独
 */

// @lc code=start
function isValidSudoku(board: string[][]): boolean {
  const m = board.length;
  const n = board[0].length;
  // 行
  const X: Map<number, number> = new Map();
  // 列
  const Y: Map<number, number> = new Map();
  // 3*3宫格
  const Z: Map<number, number> = new Map();

  for (let i = 0; i < m; i++) {
    for (let j = 0; j < n; j++) {
      if (board[i][j] === '.') continue;
      const num = Number(board[i][j]);
      // 计算当前元素在哪个3*3宫格内
      const cell = ((i / 3) >> 0) * 3 + ((j / 3) >> 0);
      let x = X.get(i) || 0;
      let y = Y.get(j) || 0;
      let z = Z.get(cell) || 0;
      // 同行、列、3*3宫格内出现重复数字
      if (x & (1 << num)) return false;
      if (y & (1 << num)) return false;
      if (z & (1 << num)) return false;
      // 将当前元素放入到哈希中保存
      X.set(i, x | (1 << num));
      Y.set(j, y | (1 << num));
      Z.set(cell, z | (1 << num));
    }
  }

  return true;
}
// @lc code=end
